<?php
namespace Lib;

use Lib\Source\DriverFactory,
    Lib\Source\DriverInterface,
    Lib\Source\DriverException,
    Lib\Data;
    
class Source implements DriverInterface{
    const DRIVER_ZEND_REGISTRY = 'Zend\\Registry';
    const DRIVER_ZEND_SESSION  = 'Zend\\Session';
    const DRIVER_ZEND_COOKIE   = 'Zend\\Cookie';
    const DRIVER_MEMCACHE      = 'Memcache';
    const DRIVER_REDIS         = 'Redis';
    const DRIVER_ZEND_REDIS    = 'Zend\\Redis';
    
    /**
     * @var DriverInterface
     */
    protected $_driver = null;
    
	/**
     * Set current driver
     *  
     * @param DriverInterface $driver
     */
    public function setDriver(DriverInterface $driver){
        $this->_driver = $driver;
    }
    
    /**
     * Init new driver and set it to defaults
     * 
     * @param string $driverName
     * @param array $driverOptions
     */
    public function initDriver($driverName, $driverOptions = array()){
        $this->setDriver(DriverFactory::factory($driverName, $driverOptions));
    }
    
    /**
     * Get current driver
     * @return DriverInterface
     */
    public function getDriver(){
        if(!$this->_driver instanceof DriverInterface){
            throw new DriverException('Source driver is not loaded');
        }
        return $this->_driver;
    }
    
    /**
     * @see Lib\Source.DriverInterface::getStorage()
     */
    public function getStorage(){
        return $this->getDriver()->getStorage();
    }
    
    /**
     * @see Lib\Source.DriverInterface::setStorage()
     */
    public function setStorage(Data $data){
        return $this->getDriver()->setStorage($data);
    }
    
    public function appendStorage(Data $data){
        return $this->getDriver()->appendStorage($data);
    }
	/**
     * @param DriverAbstract | string $driver
     * @param array $params
     */
    public function __construct($driver = null, $params = array()){
        if (null !== $driver){
            if(is_object($driver)){
                if(! $driver instanceof DriverInterface){
                    throw new SourceException('Given driver is not instance if DriverInterface');
                } else {
                    $driver->setOptions($params);
                    $this->setDriver($driver);
                }
            } else {
                $this->initDriver($driver, $params);
            }
        }
    }
    
	/**
     * @see Lib\Source.DriverInterface::load($name, $params)
     */
    public function load($name, $default = null){
        return $this->getDriver()->load($name, $default);
    }
    
    /**
     * @see Lib\Source.DriverInterface::save()
     */
    public function save($name = null, $value = null){
        return $this->getDriver()->save($name, $value);
    }
   
    
    /**
     * @see Lib\Source.DriverInterface::setOptions()
     */
    public function setOptions($options = array()){
        return $this->getDriver()->setOptions($options);
    }
    
    /**
     * @see Lib\Source.DriverInterface::getOptions()
     */
    public function getOptions(){
        return $this->getDriver()->getOptions();
    }
    
    /**
     * @see Lib\Source.DriverInterface::getOption()
     */
    public function getOption($name, $default = null){
        return $this->getDriver()->getOption($name, $default);
    }
    
    /**
     * @see Lib\Source.DriverInterface::saveData()
     */
    public function saveData($data){
        throw new DriverException('You cannt access to this function directly');
    }
}